// Child process
const path = require("path");
const EventEmitter = require("events");
const { Worker, MessageChannel } = require("worker_threads");
const ffi = require("@breush/ffi-napi");
const { getHctpLib } = require("./hctpLib.js");
const libDllPath = path.join(__dirname, "../../sdk/x64/libHCTP.dll");
const { deleteTmpDownloadFile } = require("./rename.js");

const database = require("./sqlite/index.js");
const utils = require("./utils.js");

const dbInstance = database.getDbInstance({
  dbPath: path.join(__dirname, "sqlite", "userUploadDownload.db"),
  isNotFoundCreate: true,
});

const promiseInitDb = database.initialize(dbInstance);

const myEmitter = new EventEmitter();

function getHctpHandle(message) {
  const hctpInstance = getHctpLib(libDllPath);
  const ppcsInitStr = message.syKeyInitString;
  const ppcsDidStr = message.syKeyDid;

  const hctpHandle = hctpInstance.hctpNewInit(ppcsInitStr, ppcsDidStr, 0x7a);
  return hctpHandle;
}

function hctpConnect(hctpHandle, callback) {
  const hctpInstance = getHctpLib(libDllPath);

  const onSuccess = ffi.Callback("void", ["int"], (netType) => {
    console.log("[hctpConnect netType]", netType);
  });
  const onFailure = ffi.Callback("void", ["int"], (errCode) => {
    console.log("[hctpConnect errCode]", errCode);
  });

  return hctpInstance.hctpConnect(hctpHandle, onSuccess, onFailure);
}

let connected = false;
let hctpHandle = false;

process.parentPort.on("message", async (event) => {
  // console.log("process.parentPort.message.event", event.data);
  await promiseInitDb;

  if (event.data.type === "closeDatabase") {
    const [port] = event.ports;
    database.closeDatabase(
      database.getDbInstance({ isNotFoundCreate: false }),
      (err) => {
        port.postMessage({ err });
      }
    );
    return;
  }

  if (event.data.type === "InsertDownloadMedia") {
    const [port] = event.ports;
    database.download.insertDownloadItems(event.data.newItems, (err) => {
      port.postMessage({ err, type: event.data.type, date: event.data.date });
    });
    return;
  }
  if (event.data.type === "InsertUploadMedia") {
    const [port] = event.ports;
    database.upload.insertUploadItems(event.data.newItems, (err) => {
      port.postMessage({ err, type: event.data.type, date: event.data.date });
    });
    return;
  }

  // console.log("event.data", event.data);

  const isDownloadMedia = event.data.type === "DownloadMediaStart";
  const isUploadMedia = event.data.type === "UploadMediaStart";

  // if (isDownloadMedia) {
  //   await utils.initRowData({
  //     isDownloadMedia,
  //     isUploadMedia,
  //     eventData: event.data,
  //     getRowFunc: database.download.getDownloadByTaskid,
  //     insertItemFunc: database.download.insertDownloadItem,
  //     updateStatusFunc: database.download.updateDownloadStatus,
  //   });
  // }
  // if (isUploadMedia) {
  //   await utils.initRowData({
  //     isDownloadMedia,
  //     isUploadMedia,
  //     eventData: event.data,
  //     getRowFunc: database.upload.getUploadByTaskid,
  //     insertItemFunc: database.upload.insertUploadItem,
  //     updateStatusFunc: database.upload.updateUploadStatus,
  //   });
  // }

  const [port] = event.ports;

  const worker = new Worker(path.join(__dirname, "./worker.js")); // 引用 worker.js 文件
  const channel = new MessageChannel();

  // 从工作线程接收消息
  channel.port1.on("message", (message) => {
    // console.log("Received from worker:", message);
    port.postMessage(message);

    if (message.type === "ended") {
      myEmitter.emit("stop-task" + message.taskid);
    }

    if (
      isUploadMedia &&
      (message.type === "progress" || message.type === "ended")
    ) {
      utils.getThrottledUpdate(message.taskid, utils.updateProgress)(
        database.upload.updateUploadStatus,
        message
      );
    }
    if (isUploadMedia && message.type === "ended") {
      utils.throttledMap.delete(message.taskid);
    }

    if (
      isDownloadMedia &&
      (message.type === "progress" || message.type === "ended")
    ) {
      utils.getThrottledUpdate(message.taskid, utils.updateProgress)(
        database.download.updateDownloadStatus,
        message
      );
    }
    if (isDownloadMedia && message.type === "ended") {
      utils.throttledMap.delete(message.taskid);
    }
  });

  const hctpInstance = getHctpLib(libDllPath);
  // console.log("hctpInstance", hctpInstance.hctpGetVersion());

  const systemKeyObj = event.data.systemKeyObj;

  // console.log("event.data", event.data);

  if (!connected) {
    hctpHandle = getHctpHandle(event.data);
    connected = hctpConnect(hctpHandle) === 0;
  }

  console.log("Successfully connected");

  // 向工作线程发送消息
  worker.postMessage(
    { port: channel.port2, ...event.data, uuid: event.data.uuid, hctpHandle },
    [channel.port2]
  );

  // #region 接收来自渲染进程的消息
  port.on("message", (message, ...reset) => {
    console.log("...message", message, reset);
    if (message && message.data.type === "hctpTransferStopTaskById") {
      const taskid = message.data.taskid;
      const taskType = message.data.value; // 0 删除 1 暂停

      console.log("[hctpHandle, taskid, taskType]", [
        hctpHandle,
        taskid,
        taskType,
      ]);
      if (taskType === 0) {
        myEmitter.once("stop-task" + taskid, () => {
          const downloadDirectory = path.join(__dirname, "../../img/");

          deleteTmpDownloadFile({ downloadDirectory, taskid: taskid });
          console.log("Delete taskid file", taskid);
        });
      }
      const result = hctpInstance.hctpTransferStopTaskById(
        hctpHandle,
        taskid,
        taskType
      );

      port.postMessage({ ...message.data, result });
    }
  });
  port.start(); // 开始接收消息
  // #endregion 接收来自渲染进程的消息
});
